<?php 
/*

 Copyright 2013 Google Inc. All Rights Reserved.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.

 This code is not supported by Google

 Sample PHP code for basic Ecommerce search implementation with the 
 Google Search Appliance.

 This code requires the php cURL module as well as Xpath support
*/

$GSA_HOST = "<your gsa hostname>";
$COLLECTION = "default_collection";
$FRONTEND = "default_frontend";
$FIELDS = "*";  // put specific fields in here to reduce your response size

$RESULTS_PER_PAGE = 20;
$MAX_FACETS = 15;  // Max # of values shown per facet
$SCRIPT_NAME = "search.php";
$CURRENCY = '$';

$BASE_URL = 
  "$GSA_HOST/search?output=xml_no_dtd&site=$COLLECTION".
  "&client=$FRONTEND&getfields=$FIELDS&filter=0&sort=date:D:S:d1";

$refinements = "";
$BODY = "";

// Determine page
$page = sprintf("%d", $_GET['page']);
if ($page == "" || $page == "0") {
  $page = 1;
}

// Refinements
$params = "";
if ($_REQUEST['restrict'] != "") {
  foreach ($_REQUEST['restrict'] as $restrict) {
    $refinements .= " inmeta:" . rawurlencode($restrict);
    $params .= "&restrict[]=" . rawurlencode($restrict); 
  }
}

$refinements = str_replace(" ","+",$refinements);
$refinements .= "&dnavs=$refinements";

// Construct the request url
$url = sprintf("%s".
               "&start=%d&num=%d".
               "&q=%s%s",
               $BASE_URL,
               (($page-1)* $RESULTS_PER_PAGE),
               $RESULTS_PER_PAGE,
	       urlencode($_GET['q']),
	       $refinements
               );

// Can use something like file_get_contents() if you don't want to use curl
// But curl has some better options for dealing with timeouts, etc.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);  //10 sec timeout
curl_setopt($ch, CURLOPT_LOW_SPEED_LIMIT, 100);
curl_setopt($ch, CURLOPT_LOW_SPEED_TIME, 10);

$results = curl_exec($ch);
$errno = curl_errno($ch);
$error = curl_error($ch);
curl_close($ch);

if ($_GET['debug'] == 1) {
  print "$url<br>\n";
}

if ($errno) {
  print "Error# $errno:<pre>$error</pre><br/>\n";
  exit();
}

$xml = new SimpleXMLElement($results);

$RESULTS = current($xml->xpath("/GSP/RES/M"));
$SPELLING = current($xml->xpath("/GSP/Spelling/Suggestion/@q"));

$COL = 1;
$BODY .= "<TABLE width=100% align=center border=0>";
if ($SPELLING != "" and $_REQUEST['restrict'] == "") {  // Don't show spelling suggestions once we've refined
  $BODY .= sprintf("<tr><td align=center>".
		   "Did you mean <b><i><a href=\"%s?q=%s\">%s</a>".
		   "</i></b></td></td>",
		   $SCRIPT_NAME,
		   urlencode($SPELLING),
		   $SPELLING);
}

// Loop through items and add to body
$items = $xml->xpath("/GSP/RES/R");
foreach ($items as $item) {
  // Usually best to use the title from metadata for display
  $title = current($item->xpath('MT[@N="title"]/@V'));
  if ($title == "") {
      $title = $item->T;  // Or grab the GSA version, not ideal
  }
  $price = current($item->xpath('MT[@N="price"]/@V'));
  $img_url = current($item->xpath('MT[@N="img_path"]/@V'));
  $url = $item->U;

  if (strlen($title) > 60) {
    $title = sprintf("%.60s...", $title);
  }
  
  if ($COL == 1) {
    $BODY .= "<tr valign=top>";
  }

  $BODY .= 
    sprintf("<td width=\"25%%\" align=center valign=top>".
            "<a href=\"%s\">".
            "<img height=100 src=\"%s\" border=0></a><br>",
            $url,
            $img_url);
  
  $BODY .= sprintf("<font size=2><a href=\"%s\">%s</a></font>",
                   $url,$title);
  if ($price != 0) {
    $BODY .= sprintf("<br/>%s%s",$CURRENCY,$price);
  }

  $BODY .= "</td>\n";
  if ($COL == 4) {
    $BODY .= "</tr>";
    $COL = 1;
  } else {
    $COL++;
  }
}
if ($COL != 1) {
  $BODY .= "</tr>";
}
$BODY .= "</table>";


// Dynamic Navigation Facets
$NARROW = "";
foreach ($xml->xpath('/GSP/RES/PARM/PMT') as $item) {
  $name = current($item->xpath("@NM"));
  $NARROW .= sprintf("<b>%s</b><br/>\n",current($item->xpath("@DN")));
  $facet_count = 0;
  $viewall = 0;
  foreach($item->PV as $value) {
    $facet_count++;
    $low = current($value->xpath("@L"));
    $high = current($value->xpath("@H"));
    $count = current($value->xpath("@C"));
    $value = current($value->xpath("@V"));
    if ($count == 0) {  // GSA returns all buckets, so don't display 0 counts
      continue;
    }

    if ($low != "" or $high != "") {
      if (preg_match("/inmeta:$name(\=|:)$value/",urldecode(urldecode($refinements)))) {
	$NARROW .= sprintf("%s%.2f - %s%.2f</a> (%d)<br/>\n",$CURRENCY,$low,$CURRENCY,$high,$count);
      } else {
	$link = "$name:$low..$high";
	$NARROW .= sprintf("<a href=\"$SCRIPT_NAME?q=%s%s&restrict[]=%s\">".
			   "%s%.2f - %s%.2f</a> (%d)<br/>\n",
			   urlencode($_GET['q']),
			   $params,
			   urlencode($link),
			   $CURRENCY,
			   $low,
			   $CURRENCY,
			   $high,
			   $count);
      }
    } else {
      if (preg_match("/inmeta:$name(\=|:)$value/",urldecode(urldecode($refinements)))) {
	$NARROW .= sprintf("%s (%d)<br/>\n",$value,$count);
      } else {
	$link = "$name=" . rawurlencode($value);
        $link = str_replace("-","%2D",$link); // - & . needs to be encoded for inmeta
        $link = str_replace(".","%2E",$link);
	$NARROW .= sprintf("<a href=\"$SCRIPT_NAME?q=%s%s&restrict[]=%s\">".
			   "%s</a> (%d)<br/>\n", 
			   urlencode($_GET['q']),
			   $params,
			   urlencode($link),
			   $value, 
			   $count);
      }
    }
    if (preg_match("/inmeta:$name(\=|:)$value/",urldecode(urldecode($refinements)))) {
      $sub_params = preg_replace("/&restrict\[\]=" . 
				 rawurlencode($name) . 
				 "[^&]+/","",$params);
      $viewall = 1;
    }
    if ($facet_count == $MAX_FACETS) {
      // Add logic here if you want to display more than MAX_FACETS
      break;
    }
  }
  
  // Display the un-refine link
  if ($viewall) {
    $NARROW .= sprintf("&nbsp;<u>".
		       "<a href=\"$SCRIPT_NAME?q=%s%s\">View All</a></u>".
		       "<br/>",
		       urlencode($_GET['q']),
		       $sub_params);
  }

  $NARROW .= "<br/>\n";
}


$TOTALPAGES = ceil($RESULTS/$RESULTS_PER_PAGE);
$pagenav_url = sprintf("$SCRIPT_NAME?q=%s%s",
                       urlencode($_GET['q']),
                       $params);
?>
<!-- link type="text/css" rel="stylesheet" href="http://www.google.com/products/intl/en_us/css/ps-style.css" -->
<style type="text/css">
#pagenav a, #pagenav .current, #pagenav .inactive {
  font-size: 11px;  padding: 2px 5px 2px 5px;  margin: 0px 1px 0px 1px;
border: 1px solid #fff; background: #fff; display:block; color: #304685;
}
#pagenav .current {
border: 1px solid #304685;  font-weight: bold;  background: #304685;
color: #fff;
}
#pagenav .inactive {
border: 1px solid #aaa;  font-weight: normal;  background: #fff; color: #aaa;
}
#pagenav a {
border: 1px solid #9aafe5; text-decoration: none; color: #304685;
}

#pagenav a:hover {
border-color: #9aafe5; background: #304685; color: #fff;
}
</style>
</head>
<body>
<img src="http://www.google.com/support/enterprise/static/gsa/docs/admin/70/gsa_doc_set/installation/images/google_logo.png" height="60" />
<form name="searchform" id="search-form" method="GET">
<input id="searchText" type="text" name="q" value="<?=$_GET['q']?>" autocomplete="off">
<input type=submit value="Search">
</form>
<hr width="100%" size=1>
<table>
<tr>
<td valign=top><?=$NARROW?></td>
<td valign=top width="800" align="center">
<?php 
    if ($RESULTS > 0) {
?>
<b>Approximately <?= $RESULTS ?> results found</b>
    <?php display_pagenav() ?>
<?php } ?>
<?=$BODY?></td>
</tr>
</table>

</body>
</html>


<?php 
function display_pagenav() {
  global $TOTALPAGES, $page, $pagenav_url;
  // Page navigation..
  // To use set variable $pagenav_url with value of target url

  if (!$NAVSIZE) { $NAVSIZE = 10;}
  if ($TOTALPAGES>1) {
    print("<div align=center>".
	  "<table border=0 cellspacing=0 cellpadding=0 id=pagenav><tr><td>");

    if ($page > 1) {
      printf("<a href=\"%s&page=%d\" class=\"nextprev\" ".
	     "title=\"Go to Previous Page\">".
	     "<b>&#171;&nbsp;Previous</b></a></td><td>", $pagenav_url,$page-1);
    } else {
      print "<div class=inactive>&#171; Previous</div></td><td>";
    }
    
    if ($TOTALPAGES>$NAVSIZE) {
      if ($page<=$NAVSIZE/2) {
        for ($j=1; $j<=$NAVSIZE; $j++) {
          if ($j==$page) {
            print "<div class=current>$j</div></td><td>";
          } else {
            printf("<a href=\"%s&page=%d\" title=\"Go to page %d\">%d</a>".
		   "</td><td>", $pagenav_url,$j,$j,$j);
          }
        }
        printf("<div class=dots>...</div></td><td><a href=\"%s&page=%d\" ".
	       "title=\"Go to page %d\">%d</a></td><td>",
	       $pagenav_url,$TOTALPAGES,$TOTALPAGES,$TOTALPAGES);
      } else if (($TOTALPAGES-$page)<=$NAVSIZE/2) {
        printf("<a href=\"%s&page=1\" title=\"Go to page 1\">1</a></td>".
	       "<td><div class=dots>...</div></td><td>",$pagenav_url);
        for ($j=$TOTALPAGES-$NAVSIZE; $j<=$TOTALPAGES; $j++) {
          if ($j==$page) {
            print "<div class=current>$j</div></td><td>";
          } else {
            printf("<a href=\"%s&page=%d\" title=\"Go to page %d\">%d</a>".
		   "</td><td>",$pagenav_url,$j,$j,$j);
          }
        }
      } else {
        printf("<a href=\"%s&page=1\" title=\"Go to page 1\">1</a></td>".
	       "<td><div class=dots>...</div></td><td>",$pagenav_url);
        for ($j=($page-($NAVSIZE/2)+1); $j<=($page+$NAVSIZE/2); $j++) {
          if ($j==$page) {
            print "<div class=current>$j</div></td><td>";
          } else {
            printf("<a href=\"%s&page=%d\" title=\"Go to page %d\">%d</a>".
		   "</td><td>",$pagenav_url,$j,$j,$j);
          }
        }
        printf("<div class=dots>...</div></td><td><a href=\"%s&page=%d\" ".
	       "title=\"Go to page %d\">%d</a></td><td>",
	       $pagenav_url,$TOTALPAGES,$TOTALPAGES,$TOTALPAGES);
      }
    }  else {
      for ($j=1; $j<=$TOTALPAGES; $j++) {
        if ($j==$page) {
          print "<div class=current>$j</div></td><td>";
        } else {
          printf("<a href=\"%s&page=%d\" title=\"Go to page %d\">%d</a>".
		 "</td><td>",$pagenav_url,$j,$j,$j);
        }
      }
    }

    if ($page < $TOTALPAGES) {
      printf("<a href=\"%s&page=%d\" title=\"Go to Next Page\">".
	     "<b>Next&nbsp;&#187;</b></a></td><td>",$pagenav_url,$page+1);
    } else {
      print "<div class=inactive>Next &#187;</div></td><td>";
    }

    print "</td></tr></table></div>";

  } else {
    // No results in recordset, don't display nav..
  }
}
?>
